home *** CD-ROM | disk | FTP | other *** search
/ ShareWare OnLine 2 / ShareWare OnLine Volume 2 (CMS Software)(1993).iso / prog / spx10.zip / SPX_DOC.ZIP / SPX_OBJ.DOC < prev    next >
Text File  |  1993-05-05  |  9KB  |  263 lines

  1. { SPX Library Version 1.0  Copyright 1993 Scott D. Ramsay }
  2.  
  3.   SPX_OBJ is the object handling unit.  It allows a easy way to
  4. keep track of multiple objects.  I'm assuming you know alittle about
  5. Dynamic data structures with linked list and OOP.  I don't know of
  6. any good books I'd recommend.  But I'm sure anything would be helpful.
  7. "And in schooll I thought that I'd never use linked lists in real life. ;) "
  8.  
  9.   Each object is a descendent of TOBJS.  All objects are added to a
  10. double linked list for the dynamic creation of numerous objects.  When
  11. removing objects from the list, we add the node to a 'kill' list which
  12. we can quickly deallocate multiple objects.
  13.  
  14.   Plist:  Is our double linked pointer type which its data points to a TOBJS
  15.  
  16.       Type
  17.         Pobjs = ^Tobjs;
  18.         Plist = ^Tlist;
  19.         Tlist = record
  20.                   item      : pobjs;
  21.                   prev,next : plist;
  22.                 end;
  23.  
  24.   Here is the basic structure of the linked lists.  Brackets [] specifies
  25. actual records or objects.
  26.  
  27.   var
  28.     head,tail : Plist;    { Head/Tail pointers to our object list }
  29.     kill      : Pkill;    { Our kill list }
  30.  
  31.                                                           |- Tail
  32.                                                          \|/
  33.     Head -->  [Node1]  <-->  [Node2] <--> [Node3] <--> [Node4] --> NIL
  34.                  |              |            |            |
  35.               [Tobj]         [Tobj]       [Tobj]       [Tobj]
  36.  
  37.  
  38.     Kill -->  [Knode1] --> [Knode2] --> NIL
  39.                  |            |
  40.                 \|/          \|/
  41.               [Node2]      [Node4]
  42.  
  43.  
  44.   In the above example we have four objects in our list.  With the
  45. second and third node in the kill list (ready to be deleted).
  46.  
  47.   That's basically the structure.  To do calcuations on each object, we
  48. just traverse the double linked list.  Lets say that the object at Node2
  49. was a space alien and was shot.  Ok its dead, so we add it to the kill list.
  50.  
  51.   After one iteration,  usually the Kill list is traversed deallocating each
  52. Node(n) from our double linked list.
  53.  
  54.     pkill = ^tkill;
  55.     tkill = record
  56.               tk   : plist;  { TK -  plist pointer To Kill }
  57.               next : pkill;
  58.             end;
  59.  
  60. ───────────────────────────────────────────────────────────────────────────
  61.  Type
  62.     TObjs = object;
  63.  
  64.   Generic object type.  TObjs is the base for all objects that
  65.   need to be handled.
  66.  
  67. VARIABLES:
  68.          powner:plist     A pointer to the object's node in the linked list;
  69.          killed:boolean   TRUE if the object was added to a kill list;
  70.          cankill:boolean  Set to TRUE if allowing the object to be added to
  71.                           the kill list. (See checkhit for better descript);
  72.          overshow:boolean In my games I traverse the list twice.  The first
  73.                           time is to display the objects that will be behind
  74.                           my character, the second time is for the objects
  75.                           that are above my character.  Set OVERSHOW to
  76.                           TRUE for the object to be an over character.
  77.                           (In the game RSQUID, the cloud objects are set
  78.                           to TRUE "Always in front", all other objects are
  79.                           set to FALSE. "Behind my main character";
  80.          id:integer       For each object type I assign a unique number.  This
  81.                           is incase I need to find certain objects while
  82.                           traversing the list
  83.  
  84. METHODS:
  85.  
  86.   ---------------------------------------------------
  87.   constructor Tobjs.init;
  88.  
  89.     Sets up the object
  90.  
  91.     DEFAULTS:
  92.        KILLED   set to FALSE
  93.        ID       set to 0
  94.        OVERSHOW set to TRUE
  95.  
  96.     OVERRIDE:  often
  97.  
  98.    Here is how you add an object to the linked list;
  99.  
  100.    var
  101.      p : plist;
  102.    begin
  103.      new(p);                    { Create a new node }
  104.      p^.item := new(Pobjs,init);{ Create the object }
  105.      p^.item^.powner := p;      { IMPORTANT! have the object point to its node }
  106.      addp(head,tail,p);         { Add the node to the list }
  107.    end;
  108.  
  109.   See the procedure Add2Kill_list for reason for " p^.item^.powner := p;"
  110.   ---------------------------------------------------
  111.   procedure TObjs.drawitemobject;
  112.  
  113.     Displays the item.
  114.  
  115.     OVERRIDE:  often
  116.  
  117.     Tobjs.drawitemobject is an empty function.  In your drawitemobject
  118.   function it will usually draw a sprite.
  119.  
  120.   ---------------------------------------------------
  121.   procedure TObjs.calcitemobject;
  122.  
  123.     Does any calcuations to the object such as changing the object's
  124.   position.
  125.  
  126.     OVERRIDE:  often
  127.  
  128.   ---------------------------------------------------
  129.   function TObjs.checkhit(hx,hy:integer;var item:pobjs):boolean;
  130.  
  131.     Return TRUE if hx,hy is in range of an object.
  132.  
  133.     HX,HY:  Location to check;
  134.     ITEM:   Tobjs that it is in conflict with
  135.  
  136.   OVERRIDE: often
  137.  
  138.    For example:
  139.  
  140.       function TMyObject.checkhit(hx,hy:integer;var item:pobjs):boolean;
  141.       begin
  142.         checkhit := (abs(hx-MyObjectX)<10) and (abs(hy-MyObjectY)<10);
  143.       end;
  144.  
  145.     This is basically a collision detection function.  For example,
  146.    Lets assume we have a Tbullet object (desendant of Tobjs) that wants
  147.    to check if it hit anyother objects in the list.  In the procedure
  148.    Tbullet.calcitemobject we would traverse the linked list calling
  149.    the checkhit function for each object in the list.  If the function
  150.    returns TRUE, then the object collided with the object.
  151.  
  152.    procedure Tbullet.calcitemobject;
  153.    var
  154.      p : plist;
  155.    begin
  156.      p := head;
  157.      while p<>nil do
  158.        begin
  159.         { Don't check for colliding bullets or dead objects }
  160.          if (p^.item^.id<>id_bullet) and not p^.item^.killed
  161.            then
  162.              if p^.item^.checkhit(bullet_x,bullet_y,@self)
  163.                then { we hit the object! }
  164.          p := p^.next;
  165.        end;
  166.    end;
  167.  
  168.   ---------------------------------------------------
  169.   destructor TObjs.done;
  170.  
  171.   Deallocates the object;
  172.  
  173.   OVERRIDE: sometimes
  174.  
  175. ───────────────────────────────────────────────────────────────────────────
  176. procedure addp(var nkbeg,nkend,p:plist);
  177.  
  178.   Add a node to the linked list
  179.  
  180.   NKBEG:  Linked list Head pointer;
  181.   NKEND:  Linked list Tail pointer;
  182.   P:      Node to add to the list
  183.  
  184. ───────────────────────────────────────────────────────────────────────────
  185. procedure deletep(var nkbeg,nkend,p:plist);
  186.  
  187.   Delete a note from the list and deallocate the object connected to it
  188.  
  189.   NKBEG:  Linked list Head pointer;
  190.   NKEND:  Linked list Tail pointer;
  191.   P:      Node to delete to the list
  192.  
  193. ───────────────────────────────────────────────────────────────────────────
  194. procedure calcitems(var nkbeg:plist);
  195.  
  196.   Traverses a linked list calling the node's object's calcitemobject method
  197.  
  198.   NKBEG: Linked list Head pointer
  199.  
  200.   NOTE: Still calls method even if the KILLED flag it true.
  201.  
  202. ───────────────────────────────────────────────────────────────────────────
  203. procedure drawitems(var nkbeg:plist;over:boolean);
  204.  
  205.   Traverses a linked list calling the node's object's drawitem object method
  206.  
  207.   NKBEG: Linked list Head pointer
  208.   OVER:  Set to TRUE to call only objects with OVERSHOW set to TRUE
  209.          Set to FALSE to call only objects with OVERSHOW set to FALSE
  210.  
  211. ───────────────────────────────────────────────────────────────────────────
  212. procedure add2kill_list(var kill:pkill;var i:plist);
  213.  
  214.   Adds a node to the kill list and sets the object's KILLED flag to TRUE.
  215.  
  216.   KILL:  Kill list to add the node;
  217.   I:     Node to add to the kill list
  218.  
  219.   This procedure is usually called with in a object's calcitemobject or
  220.   checkhit methods.  Since this is the case, you CAN'T deallocate a
  221.   object while still in the object's method. So by adding the node/object
  222.   to a kill list.  One can remove the object later.
  223.  
  224.   Each object has a pointer to its node (powner) that is passed to the
  225.   kill list.
  226.  
  227.   Example:
  228.  
  229.     function TMyObject.checkhit(hx,hy:integer;var item:pobjs):boolean;
  230.       begin
  231.         if (abs(hx-MyObjectX)<10) and (abs(hy-MyObjectY)<10)
  232.           then
  233.             begin
  234.               checkhit := true;
  235.               add2kill_list(kill,powner);
  236.             end
  237.           else checkhit := false;
  238.       end;
  239.  
  240. ───────────────────────────────────────────────────────────────────────────
  241. procedure cleankill_list(var kill:pkill;var nkbeg,nkend:plist);
  242.  
  243.    Traverses the KILL list deallocating node that are in the kill and
  244.    linked list.
  245.  
  246.    KILL:  Kill list to cleanout;
  247.    NKBEG:  Linked list Head pointer;
  248.    NKEND:  Linked list Tail pointer
  249.  
  250.    On return KILL=NIL
  251.  
  252. ───────────────────────────────────────────────────────────────────────────
  253. procedure clean_plist(var nkbeg,nkend:plist);
  254.  
  255.    Traverse the LINKED list deallocating every node.
  256.  
  257.    NKBEG:  Linked list Head pointer;
  258.    NKEND:  Linked list Tail pointer
  259.  
  260.    On return nkbeg=NIL and nkend=NIL
  261.  
  262. ───────────────────────────────────────────────────────────────────────────
  263.